package com.haoyun.common.utils;

import com.baomidou.mybatisplus.enums.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.google.common.collect.Maps;
import com.xiaoleilu.hutool.lang.Assert;
import com.xiaoleilu.hutool.util.StrUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;

/**
 * Created by twg on 2018/5/30.
 */
public class CodeAutoGeneratorUtil {

    private static Map currentMap = Maps.newConcurrentMap();

    static {
        synchronized (currentMap) {
            Resource resource = new ClassPathResource("/application.properties");
            try {
                CodeAutoGeneratorUtil.loadPropertiesFromResource(resource.getInputStream());
            } catch (IOException e) {
            }
            currentMap = CodeAutoGeneratorUtil.getCurrentMap();
        }
    }

    public static void generateByTables(String author, String outPath, boolean serviceNameStartWithI, String packageName, String... tableNames) {
        Assert.notBlank(outPath, "outPath must not be blank.");
        Assert.notBlank(packageName, "packageName must not be blank.");
        Assert.notEmpty(tableNames, "tableNames must have elements.");
        Assert.notEmpty(currentMap, "tableNames must have entries.");
        Assert.notBlank(currentMap.get("spring.datasource.url").toString(), "spring.datasource.url must not be blank.");
        Assert.notBlank(currentMap.get("spring.datasource.username").toString(), "spring.datasource.username must not be blank.");
        Assert.notBlank(currentMap.get("spring.datasource.password").toString(), "spring.datasource.password must not be blank.");
        Assert.notBlank(currentMap.get("spring.datasource.driver-class-name").toString(), "spring.datasource.driver-class-name must not be blank.");

        String dbUrl = (String) currentMap.get("spring.datasource.url");
        String dbUsername = (String) currentMap.get("spring.datasource.username");
        String dbPassword = (String) currentMap.get("spring.datasource.password");
        String dbDriverName = (String) currentMap.get("spring.datasource.driver-class-name");
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig
                .setUrl(dbUrl)
                .setUsername(dbUsername)
                .setPassword(dbPassword)
                .setDriverName(dbDriverName);
        GlobalConfig config = new GlobalConfig();
        config.setActiveRecord(true)
                .setEnableCache(false)
                .setAuthor(StringUtils.isNotBlank(author) ? author : "")
                .setOutputDir(outPath)
                .setBaseResultMap(true)
                .setBaseColumnList(true)
                .setOpen(false)
                .setIdType(IdType.ID_WORKER)
                .setFileOverride(true);
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig
                .setSuperControllerClass("com.haoyun.common.controller.BaseController")
                .setCapitalMode(true)
                .setEntityLombokModel(true)
                .setDbColumnUnderline(true)
                .setRestControllerStyle(true)
                .entityTableFieldAnnotationEnable(true)
                .setNaming(NamingStrategy.underline_to_camel)
                .setInclude(tableNames);//修改替换成你需要的表名，多个表名传数组
        if (!serviceNameStartWithI) {
            config.setServiceName("%sService");
            config.setServiceImplName("%sServiceImpl");
        }
        // 关闭默认 xml 生成，调整生成 至 根目录
        TemplateConfig tc = new TemplateConfig();
        tc.setXml(null);
        InjectionConfig ccg = new InjectionConfig() {
            @Override
            public void initMap() {

            }
        };
        ccg.setFileOutConfigList(Collections.<FileOutConfig>singletonList(new FileOutConfig("/templates/mapper.xml.vm") {
            // 自定义输出文件目录
            @Override
            public String outputFile(TableInfo tableInfo) {
                String path = StrUtil.removeSuffix(outPath, "java");
                return path + "/resources/mapper/" + tableInfo.getEntityName() + "Mapper.xml";
            }
        }));
        new AutoGenerator().setCfg(ccg)
                .setTemplate(tc)
                .setGlobalConfig(config)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategyConfig)
                .setPackageInfo(
                        new PackageConfig()
                                .setParent(packageName)
                                .setController("controller")
                                .setEntity("model.entity")
                                .setMapper("mapper")
                ).execute();
    }


    public static void generateByTables(String author, String outPath, String packageName, String... tableNames) {
        generateByTables(author, outPath, true, packageName, tableNames);
    }

    public static void loadPropertiesFromResource(InputStream inputStream) throws IOException {
        Properties props = PropertiesUtil.loadPropertiesFromInputStream(inputStream);
        currentMap = PropertiesUtil.loadProperties(props);
    }

    public static Map getCurrentMap() {
        return currentMap;
    }
}
